package com.cetcs.kmga.common;

import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 大数据工具类
 *
 * @author xutao
 * @version V1.0 创建时间：2017-08-30 15:46
 *          Copyright 2017 by CETC
 */
public class HBaseUtil {

    private final static Logger LOGGER = LoggerFactory.getLogger(HBaseUtil.class);

    volatile private static HBaseUtil instance = null;


    private HBaseUtil() {
    }

    /**
     * 单例模式，保证服务启动后获取的工具实体只有一个，避免创建多个工具类
     *
     * @return
     */
    public static HBaseUtil getInstance() {
        try {
            if (instance == null) {//懒汉式
                //创建实例之前可能会有一些准备性的耗时工作
                Thread.sleep(300);
                synchronized (HBaseUtil.class) {
                    if (instance == null) {//二次检查
                        instance = new HBaseUtil();
                    }
                }
            }
        } catch (InterruptedException e) {
            LOGGER.error("获取大数据工具类实体出错");
        }
        return instance;
    }


    /**
     * 返回带分页的查询Page结果
     * 分页结果采用的按全表查询出来之后截取分页
     *
     * @param sql      查询条件
     * @param keywords 参数
     * @param page     当前页
     * @param pageSize 每页显示多少条
     * @return
     */
    public Page queryListByPage(String sql, List<String> keywords, int page, int pageSize) {
        List<Map<String, Object>> ret = queryList(sql, keywords);
        if (ret != null && ret.size() > 0) {
            Page retPage = new Page();
            int totalPageCount = ret.size() % pageSize > 0 ? (ret.size() / pageSize) + 1 : ret.size() / pageSize;
            retPage.setContent(ret);
            retPage.setPageNumber(page);
            retPage.setPageSize(pageSize);
            retPage.setTotalPageCount(totalPageCount);
            retPage.setTotalRecord(ret.size());
            return retPage;

        }
        return null;
    }

    /**
     * 不带条件的分页查询
     *
     * @param sql      查询条件
     * @param page     当前页
     * @param pageSize 每页显示多少条
     * @return
     */
    public Page queryListByPageNoQueryCondition(String sql, int page, int pageSize) {

        return queryListByPage(sql, null, page, pageSize);
    }

    /**
     * 截取需要当前的数据
     *
     * @param page         当前页
     * @param pageSize     每页第几页
     * @param allCacheList 统计数组
     * @return
     */
    private List<?> subListChildren(int page, int pageSize, List<?> allCacheList) {
        List<?> subChildrenList = new ArrayList<>();
        if (allCacheList != null && allCacheList.size() > 0) {
            int totalPageCount = allCacheList.size() % pageSize > 0 ? (allCacheList.size() / pageSize) + 1 : allCacheList.size() / pageSize;
            //取出前端需要的值
            if (page == totalPageCount) {
                subChildrenList = allCacheList.subList(pageSize * (page - 1), allCacheList.size());
            } else {
                subChildrenList = allCacheList.subList(pageSize * (page - 1), pageSize * page);
            }
        }
        return subChildrenList;
    }

    /**
     * 不带条件的查询方式
     *
     * @param sql
     * @return
     */
    public List<Map<String, Object>> queryListNoQueryCondition(String sql) {
        return queryListBy(sql, null);
    }

    /**
     * 不指定参数类型的查询
     *
     * @param sql
     * @param keywords 参数
     * @return
     */
    public List<Map<String, Object>> queryListBy(String sql, List<Object> keywords) {
        Connection conn = null;
        ResultSet rs = null;
        PreparedStatement statement = null;
        List<Map<String, Object>> ret = null;
        try {
            conn = DruidPool.getInstance().getConnection();
            statement = conn.prepareStatement(sql);
            //开始填充参数
            if (keywords != null && keywords.isEmpty()) {
                for (int i = 1; i <= keywords.size(); i++) {
                    statement.setObject(i, keywords.get(i));
                }
            }
            rs = statement.executeQuery();
            ResultSetMetaData data = rs.getMetaData();
            ret = Lists.newArrayList();
            while (rs.next()) {
                Map<String, Object> map = new HashMap<>();
                for (int i = 1; i <= data.getColumnCount(); i++) {// 数据库里从 1 开始
                    String c = data.getColumnName(i);
                    Object v = rs.getObject(c);
                    map.put(c, v);
                }
                ret.add(map);
            }
        } catch (SQLException ex) {
            LOGGER.error(" query is error,error reason: " + ex.getMessage());
            ret = null;
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (statement != null) {
                    statement.close();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            DruidPool.close(conn);
        }
        return ret;
    }


    /**
     * 返回List<Map<String,Object>> 的查询
     *
     * @param sql      sql语句，
     * @param keywords 参数，填充为字符串
     * @return
     */
    public List<Map<String, Object>> queryList(String sql, List<String> keywords) {
        Connection conn = null;
        ResultSet rs = null;
        PreparedStatement statement = null;
        List<Map<String, Object>> ret = null;
        try {
            conn = DruidPool.getInstance().getConnection();
            statement = conn.prepareStatement(sql);
            //开始填充参数
            if (keywords != null && keywords.size() > 0) {
                for (int i = 1; i <= keywords.size(); i++) {
                    statement.setString(i, keywords.get(i));
                }
            }
            rs = statement.executeQuery();
            ResultSetMetaData data = rs.getMetaData();
            ret = Lists.newArrayList();
            while (rs.next()) {
                Map<String, Object> map = new HashMap<>();
                for (int i = 1; i <= data.getColumnCount(); i++) {// 数据库里从 1 开始
                    String c = data.getColumnName(i).toUpperCase();
                    Object v = rs.getObject(c);
                    map.put(c, v);
                }
                ret.add(map);
            }
        } catch (SQLException ex) {
            LOGGER.error(" query is error,error reason: " + ex.getMessage());
            ret = null;
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (statement != null) {
                    statement.close();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            DruidPool.close(conn);
        }
        return ret;
    }


}
